﻿using System.Collections.Generic;
using System.Data.SqlClient;
using System.Linq;
using BLL.Models.Users;
using BLL.Security;
using BLL.Services.Users.Listing;

namespace BLL.Services.Users
{
    public class UsersService : IUsersService
    {
        private readonly UsersCollection _usersCollection;

        public UsersService(UsersCollection collection)
        {
            _usersCollection = collection;
        }


        public User GetUserById(int userId)
        {
            return _usersCollection.SelectById(userId);
        }

        public AuthenticationStatus Authenticate(string email, string password)
        {
            var user = GetUserByEmailOrLogin(email);
            if (user == null)
            {
                return AuthenticationStatus.NotFound;
            }
            if (user.Status == UserStatus.Inactive)
                return AuthenticationStatus.Disabled;
            if (user.Status == UserStatus.NotVerified)
                return AuthenticationStatus.NotVerified;
            if (!string.IsNullOrEmpty(password))
            {
                byte[] salt = user.Salt;
                byte[] encryptedPassword = Cryptographer.GenerateHash(password, salt);

                if (!encryptedPassword.SequenceEqual(user.PasswordHash))
                {
                    return AuthenticationStatus.PaswordInvalid;
                }
                return AuthenticationStatus.Success;
            }
            return AuthenticationStatus.PaswordInvalid;
        }

        public void Create(User user)
        {
            try
            {
                _usersCollection.Create(user);
            }
            catch (SqlException sqlException)
            {
                throw new ServiceException(sqlException.Message);
            }
        }

        public void Save(User user)
        {
            try
            {
                _usersCollection.Save(user);
            }
            catch (SqlException sqlException)
            {
                throw new ServiceException(sqlException.Message);
            }
        }

        public bool ValidateUser(int userId, string email, string login)
        {
            try
            {
                return _usersCollection.ValidateUser(userId, email, login);
            }
            catch (SqlException sqlException)
            {
                throw new ServiceException(sqlException.Message);
            }
        }

        public void Delete(int userId)
        {
            try
            {
                _usersCollection.Delete(userId);
            }
            catch (SqlException sqlException)
            {
                throw new ServiceException(sqlException.Message);
            }
        }

        public User GetUserByEmailOrLogin(string userName)
        {
            return _usersCollection.GetByEmailOrLogin(userName);
        }

        public UserListing GetUserListing(int page, int size, string column, int direction, UserFilter filter)
        {
            return _usersCollection.GetUserListing(page, size, column, direction, filter);
        }

        public IEnumerable<User> GetAllUsers
        {
            get
            {
                return _usersCollection.SelectAll();
            }
        }
    }
}